﻿using Furion.FriendlyException;
using Gear.Core.ErrorControl;
using Gear.ToolKits.Helper;
using Gear.Web.Api.DynamicDataApi.Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Gear.Web.Api.DynamicDataApi.Macro
{
    /// <summary>
    /// 查询条件宏
    /// </summary>
    public static class FactorMacro
    {
        
        private static readonly string Queryword = "querying";// 查询标识关键字

        /// <summary>
        /// 查询条件匹配
        /// </summary>
        /// <param name="_content"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public static string FactorTrans(string _content,Dictionary<string, object> param)
        {
            StringBuilder sb = new(_content);

            param.TryGetValue(Queryword, out object Value); if (Value == null) return _content;

            var QueryMod = JsonHelper.DeserializeJSON<List<Querys>>(Value.ToString());

            if (QueryMod != null && QueryMod.Count > 0)
            {
                // 验证查询关键字是否是源数据字段
                CheckIsDataKey(QueryMod);
                QueryMod.ForEach(m => {
                    switch ((ExpressionType)m.Expression)
                    {
                        case ExpressionType.AllLike:
                            sb.Append($" and {m.QueryKey} like '%{m.QueryValue[0]}%'");
                            break;
                        case ExpressionType.FirstLike:
                            sb.Append($" and {m.QueryKey} like '{m.QueryValue[0]}%'"); 
                            break;
                        case ExpressionType.LastLike:
                            sb.Append($" and {m.QueryKey} like '%{m.QueryValue[0]}'");
                            break;
                        case ExpressionType.Equal:
                            sb.Append($" and {m.QueryKey}='{m.QueryValue[0]}'");
                            break;
                        case ExpressionType.NoEqual:
                            sb.Append($" and {m.QueryKey}<>'{m.QueryValue[0]}'");
                            break;
                        case ExpressionType.Less:
                            sb.Append($" and {m.QueryKey}<'{m.QueryValue[0]}'");
                            break;
                        case ExpressionType.LessOrEqual:
                            sb.Append($" and {m.QueryKey}<='{m.QueryValue[0]}'");
                            break;
                        case ExpressionType.Greater:
                            sb.Append($" and {m.QueryKey}>'{m.QueryValue[0]}'");
                            break;
                        case ExpressionType.GreaterOrEqual:
                            sb.Append($" and {m.QueryKey}>='{m.QueryValue[0]}'");
                            break;
                        case ExpressionType.Exist:
                            sb.Append($" and {m.QueryKey} in ({GetListValue(m.QueryValue)})");
                            break;
                        case ExpressionType.NoExist:
                            sb.Append($" and {m.QueryKey} not in ({GetListValue(m.QueryValue)})");
                            break;
                        case ExpressionType.Between:
                            sb.Append($" and {m.QueryKey} between '{m.QueryValue[0]}' and '{m.QueryValue[1]}'");
                            break;
                        default:
                            throw Oops.Oh(ErrorCodeModel.E1200_4_1, m.Expression);
                    }

                });
            }

            return sb.ToString();
        }

        #region == ToolKits ==
        private static string GetListValue(List<object> list)
        {
            StringBuilder sb = new ();
            int i = 0;
            list.ForEach(x => { 
                if(i==0) sb.Append($"'{x}'");
                else sb.Append($",'{x}'");
                i++;
            });

            return sb.ToString();
        }

        private static void CheckIsDataKey(List<Querys> Querys)
        {
            Querys.ForEach(x => {
                var key=x.QueryKey;
                if (false) throw Oops.Oh(ErrorCodeModel.E1200_4_2, key);
            });
            
        }
        #endregion
    }
}
